// src/utils/axios.js
import axios from "axios";
import { ElMessage, ElMessageBox } from "element-plus";

// 统一 axios 单例：
// - 开发环境 (import.meta.env.DEV === true)：使用 /api，配合 Vite proxy
// - 生产环境：使用 VITE_API_URL（由部署时注入），如果未配置则打印警告

const DEFAULT_TIMEOUT = 10000;

function resolveBaseURL() {
  // 当在 dev 模式下，使用相对路径 /api 以走 Vite 的 proxy
  if (import.meta.env.DEV) return "/api";
  // 生产环境：使用环境变量 VITE_API_URL
  const prod = import.meta.env.VITE_API_URL || "";
  if (!prod) {
    // 生产未配置后端地址时打印提示（但仍允许相对请求）
    // eslint-disable-next-line no-console
    console.warn(
      "VITE_API_URL is not set. Production build will use relative URLs. If backend is remote, set VITE_API_URL."
    );
  }
  return prod;
}

const baseURL = resolveBaseURL();

// 单例 axios 实例
const axiosInstance = axios.create({
  baseURL,
  withCredentials: true,
  timeout: DEFAULT_TIMEOUT,
});

// 工具：处理 .json 后缀（在生产环境如果需要可去掉）
function handleJsonSuffix(url) {
  if (!url) return url;
  if (!import.meta.env.DEV && url.indexOf(".json") !== -1) {
    return url.replace(".json", "");
  }
  return url;
}

// 请求拦截：注入 token 等
axiosInstance.interceptors.request.use(
  (config) => {
    console.log('发送请求:', {
      url: config.url,
      method: config.method,
      data: config.data,
      headers: config.headers
    });
    // 注入 token（如果存在）
    try {
      const token = localStorage.getItem("token");
      if (token) {
        config.headers = config.headers || {};
        if (!config.headers.Authorization) {
          config.headers.Authorization = `Bearer ${token}`;
        }
      }
    } catch (e) {
      // ignore
    }

    // 可选：在生产环境去掉 .json 后缀
    if (config.url) config.url = handleJsonSuffix(config.url);

    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截：统一业务层处理
axiosInstance.interceptors.response.use(
  (response) => {
    // 调试：打印响应体，帮助定位后端返回的字段结构
    try {
      console.log('收到响应:', response && response.data);
    } catch (e) {
      // ignore logging errors
    }
    const res = response && response.data;

    // 若后端使用 { state, message, ... } 结构统一返回
    if (res && typeof res.state !== "undefined") {
      if (res.state > 0) {
        ElMessage.error(res.message || "系统出错");
        // 中断 Promise 链（沿用原项目行为），也可以改为 reject(new Error(...))
        return new Promise(() => {});
      }

      if (res.state === -1) {
        ElMessageBox.alert("登录已经过期，请重新登录", "登录过期", {
          confirmButtonText: "重新登录",
          callback: () => {
            window.location.href = "/login";
          },
        });
        return new Promise(() => {});
      }

      // 成功返回业务数据（方便调用方直接拿到数据）
      return res;
    }

    // 若没有 state 字段，直接返回 response.data
    return res;
  },
  (error) => {
    // 当请求出错（包括 4xx/5xx）时，打印更多信息以便调试
    try {
      console.error('请求错误：', error);
      if (error.response) {
        console.error('错误响应 body:', error.response.data);
        console.error('错误响应 status:', error.response.status);
      }
      // 打印原始响应文本（有时后端返回 HTML 或未解析的文本）
      try {
        console.error('原始响应文本:', error.request && error.request.responseText);
      } catch (e) {}
    } catch (e) {}

    // 当 proxy 目标不可达时，axios 会抛出 ECONNREFUSED，此处统一提示
    const msg = (error && error.message) || "请求失败";
    // 如果后端返回了可读的错误信息，优先显示它
    const serverMsg = error?.response?.data?.message || error?.response?.data || null;
    ElMessage.error(serverMsg || msg);
    return Promise.reject(error);
  }
);

// 辅助导出：获取实例和设置 baseURL（运行时可调整，方便测试）
function getInstance() {
  return axiosInstance;
}

function setBaseURL(url) {
  axiosInstance.defaults.baseURL = url;
}

// 创建一个新的 axios 实例并附加相同的拦截器（用于按模块或按 baseURL 创建独立实例）
function attachInterceptors(instance) {
  // 请求拦截
  instance.interceptors.request.use(
    (config) => {
      try {
        const token = localStorage.getItem("token");
        if (token) {
          config.headers = config.headers || {};
          if (!config.headers.Authorization) {
            config.headers.Authorization = `Bearer ${token}`;
          }
        }
      } catch (e) {
        // ignore
      }
      if (config.url) config.url = handleJsonSuffix(config.url);
      return config;
    },
    (error) => Promise.reject(error)
  );

  // 响应拦截
  instance.interceptors.response.use(
    (response) => {
      // 调试：打印响应体（用于通过 createRequest 创建的实例）
      try {
        console.log('收到响应(实例):', response && response.data);
      } catch (e) {}
      const res = response && response.data;
      if (res && typeof res.state !== "undefined") {
        if (res.state > 0) {
          ElMessage.error(res.message || "系统出错");
          return new Promise(() => {});
        }
        if (res.state === -1) {
          ElMessageBox.alert("登录已经过期，请重新登录", "登录过期", {
            confirmButtonText: "重新登录",
            callback: () => {
              window.location.href = "/login";
            },
          });
          return new Promise(() => {});
        }
        return res;
      }
      return res;
    },
    (error) => {
      try {
        console.error('请求错误(实例)：', error);
        if (error.response) {
          console.error('错误响应 body(实例):', error.response.data);
          console.error('错误响应 status(实例):', error.response.status);
        }
        try {
          console.error('原始响应文本(实例):', error.request && error.request.responseText);
        } catch (e) {}
      } catch (e) {}
      const msg = (error && error.message) || "请求失败";
      const serverMsg = error?.response?.data?.message || error?.response?.data || null;
      ElMessage.error(serverMsg || msg);
      return Promise.reject(error);
    }
  );
  return instance;
}

function createRequest(baseURLOrPath, timeout = DEFAULT_TIMEOUT) {
  // 支持传入相对路径（例如 "/epgms" 或 "api/population_change"）或完整地址
  let base = baseURLOrPath;
  if (!base) base = resolveBaseURL();

  const cfg = {
    baseURL: base,
    withCredentials: true,
    timeout: timeout,
  };

  const inst = axios.create(cfg);
  attachInterceptors(inst);
  return inst;
}

export default axiosInstance;
export { getInstance, setBaseURL, createRequest };